struct ReflectedLight {
    directDiffuse : vec3 <f32>,
    directSpecular : vec3 <f32>,
    indirectDiffuse : vec3 <f32>,
    indirectSpecular : vec3 <f32>,
};
struct Geometry {
    position : vec3 <f32>,
    normal : vec3 <f32>,
    viewDir : vec3 <f32>,
    #if USE_CLEARCOAT
        vec3 clearcoatNormal;
    #endif
};
fn getAmbientLightIrradiance(ambientLightColor : vec3 <f32>) -> vec3 <f32> {
    let irradiance = ambientLightColor;
    return irradiance;
}
fn getDistanceAttenuation(lightDistance : f32, cutoffDistance : f32, decayExponent : f32) -> f32 {
    if (cutoffDistance > 0.0 && decayExponent > 0.0)
    {
        let x : f32 = saturate(- lightDistance / cutoffDistance + 1.0);
        return pow(x, decayExponent);
    }
    return 1.0;
}
fn getSpotAttenuation(coneCosine : f32, penumbraCosine : f32, angleCosine : f32) -> f32 {
    return smoothstep(coneCosine, penumbraCosine, angleCosine);
}
fn shGetIrradianceAt(normal : vec3 <f32>, shCoefficients : array<vec3 <f32>, 9>) -> vec3 <f32> {
    let x : f32 = normal.x;
    let y : f32 = normal.y;
    let z : f32 = normal.z;
    var result : vec3 <f32> = shCoefficients[ 0 ] * 0.886227;
    result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;
    result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;
    result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;
    result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;
    result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;
    result += shCoefficients[ 6 ] * (0.743125 * z * z - 0.247708);
    result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;
    result += shCoefficients[ 8 ] * 0.429043 * (x * x - y * y);
    return result;
}
fn inverseTransformDirection(dir : vec3 <f32>, matrix : mat4x4 <f32>) -> vec3 <f32> {
    return normalize((vec4 <f32> (dir, 0.0) * matrix).xyz);
}
